package com.balloon.gateway.security.manager;

import com.balloon.gateway.enums.StatusCodeEnums;
import com.balloon.gateway.exception.SmsCodeErrorException;
import com.balloon.gateway.redis.RedisUtils;
import com.balloon.gateway.security.service.UserSmsDetailsServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;



/**
 * @author liaofuxing
 * @version 1.0.0
 * @date 2022/3/8 11:12
 * @description 短信校验授权管理器
 */
@Component
public class SmsAuthenticationManager implements ReactiveAuthenticationManager {
    private static final Logger log = LoggerFactory.getLogger(SmsAuthenticationManager.class);

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    UserSmsDetailsServiceImpl userSmsDetailsServiceImpl;

    @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        RedisUtils redisUtils = new RedisUtils(stringRedisTemplate);
        String redisSMSCode = redisUtils.get("SYSTEM_USER_SMS_CODE:" + authentication.getPrincipal());
        if(StringUtils.isEmpty(redisSMSCode)){
            return Mono.empty();
        }else {
            if (authentication.getCredentials().equals(redisSMSCode)) {
                return Mono.just(authentication).map(auth -> userSmsDetailsServiceImpl.findByByPhone(auth.getPrincipal().toString()))
                        .map(user -> new UsernamePasswordAuthenticationToken(
                                user,
                                null,
                                user.getAuthorities()));
            }else {
                return Mono.error(new SmsCodeErrorException(String.valueOf(StatusCodeEnums.SMS_CODE_ERROR.getCode()),StatusCodeEnums.SMS_CODE_ERROR.getName()));
            }
        }
    }
}